const fs = require("fs-extra");
const path = require("path");
const yaml = require("js-yaml");
const { extractYamlFromAgent } = require("../../lib/yaml-utils");

class ConfigLoader {
    constructor() {
        this.configPath = path.join(
            __dirname,
            "..",
            "config",
            "install.config.yaml"
        );
        this.config = null;
    }

    async load() {
        if (this.config) return this.config;

        try {
            const configContent = await fs.readFile(this.configPath, "utf8");
            this.config = yaml.load(configContent);
            return this.config;
        } catch (error) {
            throw new Error(`加载配置失败：${error.message}`);
        }
    }

    async getInstallationOptions() {
        const config = await this.load();
        return config["installation-options"] || {};
    }

    async getAvailableAgents() {
        const agentsDir = path.join(this.getSdatCorePath(), "agents");

        try {
            const entries = await fs.readdir(agentsDir, {
                withFileTypes: true,
            });
            const agents = [];

            for (const entry of entries) {
                if (entry.isFile() && entry.name.endsWith(".md")) {
                    const agentPath = path.join(agentsDir, entry.name);
                    const agentId = path.basename(entry.name, ".md");

                    try {
                        const agentContent = await fs.readFile(
                            agentPath,
                            "utf8"
                        );

                        // Extract YAML block from agent file
                        const yamlContentText =
                            extractYamlFromAgent(agentContent);
                        if (yamlContentText) {
                            const yamlContent = yaml.load(yamlContentText);
                            const agentConfig = yamlContent.agent || {};

                            agents.push({
                                id: agentId,
                                name:
                                    agentConfig.title ||
                                    agentConfig.name ||
                                    agentId,
                                file: `sdat-core/agents/${entry.name}`,
                                description:
                                    agentConfig.whenToUse ||
                                    "No description available",
                            });
                        }
                    } catch (error) {
                        console.warn(
                            `读取智能体 ${entry.name} 失败：${error.message}`
                        );
                    }
                }
            }

            // Sort agents by name for consistent display
            agents.sort((a, b) => a.name.localeCompare(b.name));

            return agents;
        } catch (error) {
            console.warn(`读取智能体目录失败：${error.message}`);
            return [];
        }
    }

    async getAvailableExpansionPacks() {
        const expansionPacksDir = path.join(
            this.getSdatCorePath(),
            "..",
            "expansion-packs"
        );

        try {
            const entries = await fs.readdir(expansionPacksDir, {
                withFileTypes: true,
            });
            const expansionPacks = [];

            for (const entry of entries) {
                if (entry.isDirectory() && !entry.name.startsWith(".")) {
                    const packPath = path.join(expansionPacksDir, entry.name);
                    const configPath = path.join(packPath, "config.yaml");

                    try {
                        // Read config.yaml
                        const configContent = await fs.readFile(
                            configPath,
                            "utf8"
                        );
                        const config = yaml.load(configContent);

                        expansionPacks.push({
                            id: entry.name,
                            name: config.name || entry.name,
                            description:
                                config["short-title"] ||
                                config.description ||
                                "无描述",
                            fullDescription:
                                config.description ||
                                config["short-title"] ||
                                "无描述",
                            version: config.version || "1.0.0",
                            author: config.author || "SDAT 团队",
                            packPath: packPath,
                            dependencies: config.dependencies?.agents || [],
                        });
                    } catch (error) {
                        // Fallback if config.yaml doesn't exist or can't be read
                        console.warn(
                            `读取扩展包 ${entry.name} 的配置文件失败：${error.message}`
                        );

                        // Try to derive info from directory name as fallback
                        const name = entry.name
                            .split("-")
                            .map(
                                (word) =>
                                    word.charAt(0).toUpperCase() + word.slice(1)
                            )
                            .join(" ");

                        expansionPacks.push({
                            id: entry.name,
                            name: name,
                            description: "No description available",
                            fullDescription: "No description available",
                            version: "1.0.0",
                            author: "SDAT Team",
                            packPath: packPath,
                            dependencies: [],
                        });
                    }
                }
            }

            return expansionPacks;
        } catch (error) {
            console.warn(`读取扩展包目录失败：${error.message}`);
            return [];
        }
    }

    async getAgentDependencies(agentId) {
        // Use DependencyResolver to dynamically parse agent dependencies
        const DependencyResolver = require("../../lib/dependency-resolver");
        const resolver = new DependencyResolver(
            path.join(__dirname, "..", "..", "..")
        );

        const agentDeps = await resolver.resolveAgentDependencies(agentId);

        // Convert to flat list of file paths
        const depPaths = [];

        // Core files and utilities are included automatically by DependencyResolver

        // Add agent file itself is already handled by installer

        // Add all resolved resources
        for (const resource of agentDeps.resources) {
            const filePath = `.sdat-core/${resource.type}/${resource.id}.md`;
            if (!depPaths.includes(filePath)) {
                depPaths.push(filePath);
            }
        }

        return depPaths;
    }

    async getIdeConfiguration(ide) {
        const config = await this.load();
        const ideConfigs = config["ide-configurations"] || {};
        return ideConfigs[ide] || null;
    }

    getSdatCorePath() {
        // Get the path to sdat-core relative to the installer (now under tools)
        return path.join(__dirname, "..", "..", "..", "sdat-core");
    }

    getDistPath() {
        // Get the path to dist directory relative to the installer
        return path.join(__dirname, "..", "..", "..", "dist");
    }

    getAgentPath(agentId) {
        return path.join(this.getSdatCorePath(), "agents", `${agentId}.md`);
    }

    async getAvailableTeams() {
        const teamsDir = path.join(this.getSdatCorePath(), "agent-teams");

        try {
            const entries = await fs.readdir(teamsDir, { withFileTypes: true });
            const teams = [];

            for (const entry of entries) {
                if (entry.isFile() && entry.name.endsWith(".yaml")) {
                    const teamPath = path.join(teamsDir, entry.name);

                    try {
                        const teamContent = await fs.readFile(teamPath, "utf8");
                        const teamConfig = yaml.load(teamContent);

                        if (teamConfig.bundle) {
                            teams.push({
                                id: path.basename(entry.name, ".yaml"),
                                name: teamConfig.bundle.name || entry.name,
                                description:
                                    teamConfig.bundle.description ||
                                    "Team configuration",
                                icon: teamConfig.bundle.icon || "📋",
                            });
                        }
                    } catch (error) {
                        console.warn(
                            `读取团队 ${entry.name} 的配置文件失败：${error.message}`
                        );
                    }
                }
            }

            return teams;
        } catch (error) {
            console.warn(`读取团队目录失败：${error.message}`);
            return [];
        }
    }

    getTeamPath(teamId) {
        return path.join(
            this.getSdatCorePath(),
            "agent-teams",
            `${teamId}.yaml`
        );
    }

    async getTeamDependencies(teamId) {
        // Use DependencyResolver to dynamically parse team dependencies
        const DependencyResolver = require("../../lib/dependency-resolver");
        const resolver = new DependencyResolver(
            path.join(__dirname, "..", "..", "..")
        );

        try {
            const teamDeps = await resolver.resolveTeamDependencies(teamId);

            // Convert to flat list of file paths
            const depPaths = [];

            // Add team config file
            depPaths.push(`.sdat-core/agent-teams/${teamId}.yaml`);

            // Add all agents
            for (const agent of teamDeps.agents) {
                const filePath = `.sdat-core/agents/${agent.id}.md`;
                if (!depPaths.includes(filePath)) {
                    depPaths.push(filePath);
                }
            }

            // Add all resolved resources
            for (const resource of teamDeps.resources) {
                const filePath = `.sdat-core/${resource.type}/${resource.id}.${resource.type === "workflows" ? "yaml" : "md"}`;
                if (!depPaths.includes(filePath)) {
                    depPaths.push(filePath);
                }
            }

            return depPaths;
        } catch (error) {
            throw new Error(`读取团队 ${teamId} 的依赖失败：${error.message}`);
        }
    }
}

module.exports = new ConfigLoader();
